package com.service.healthycode.task;

import com.alibaba.fastjson.JSONObject;
import com.service.config.constant.ApiUrlConstants;
import com.service.config.utils.JsonXMLUtils;
import com.service.config.utils.StringUtils;
import com.service.healthycode.dto.SmsCode;
import com.service.healthycode.dto.SmsSendResponseDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.service.config.constant.ApiUrlConstants.SMS_URL;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;

/**
 * @ClassName: Test
 * @Description:
 * @Author guochuang
 * @Date 2022/1/10
 * @Version 1.0
 */
@Service
@Slf4j
public class SendSmsOne {
    @Resource
    private RestTemplate restTemplate;
    private static final String WSSE_HEADER_FORMAT = "UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"";
    //无需修改,用于格式化鉴权头域,给"Authorization"参数赋值
    private static final String AUTH_HEADER_VALUE = "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"";
    public void sendSms(SmsCode smsCode, int i) {
        //请求Headers参数
        String receiver = "+86"+smsCode.getTelephone(); //短信接收人号码
        String randomNum = smsCode.getCode();
        String templateParas = "[\""+randomNum+"\"]";
        //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
        String statusCallBack = "";
        //请求Body,不携带签名名称时,signature请填null
        String body = buildRequestBody(ApiUrlConstants.SMS_SENDER, receiver,"", "", statusCallBack, "",randomNum, i);
        if (null == body || body.isEmpty()) {
            log.info("body is null.");
            return;
        }
        log.info(body+"body");
        //请求Headers中的X-WSSE参数值
        String wsseHeader = buildWsseHeader(ApiUrlConstants.SMS_APP_KEY, ApiUrlConstants.SMS_APP_SECRET);
        if (null == wsseHeader || wsseHeader.isEmpty()) {
            log.info("wsse header is null.");
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", AUTH_HEADER_VALUE);
        headers.add("X-WSSE", wsseHeader);
        headers.setContentType(APPLICATION_FORM_URLENCODED);
        HttpEntity<String> r = new HttpEntity<String>(body, headers);
        try {
            ResponseEntity<JSONObject> response = restTemplate.postForEntity(SMS_URL, r, JSONObject.class);
            JSONObject code = Objects.requireNonNull(response.getBody());
            SmsSendResponseDto smsSendResponseDto = code.toJavaObject(SmsSendResponseDto.class);
            if (!smsSendResponseDto.getCode().equals("000000")) {
                log.error(JsonXMLUtils.obj2json(smsSendResponseDto));
            }
            log.info(JsonXMLUtils.obj2json(smsSendResponseDto));
        } catch (Exception e) {
            log.error( e.getMessage());
        }

    }
    /**
     * 构造请求Body体
     * @param sender
     * @param receiver
     * @param templateId
     * @param templateParas
     * @param statusCallBack
     * @param signature | 签名名称,使用国内短信通用模板时填写
     * @return
     */
    static String buildRequestBody(String sender, String receiver, String templateId, String templateParas,
                                   String statusCallBack, String signature,String randomNum,int i) {
        if (null == sender || null == receiver || sender.isEmpty() || receiver.isEmpty()){
            log.info("buildRequestBody(): sender, receiver is null.");
            return null;
        }
        Map<String, String> map = new HashMap<String, String>();

        map.put("from", sender);
        map.put("to", receiver);
        if (null != templateId && !templateId.isEmpty()) {
            map.put("templateId", templateId);
        }
        if (null != templateParas && !templateParas.isEmpty()) {
            map.put("templateParas", templateParas);
        }
        if (null != statusCallBack && !statusCallBack.isEmpty()) {
            map.put("statusCallback", statusCallBack);
        }
        if (null != signature && !signature.isEmpty()) {
            map.put("signature", signature);
        }
        if (!StringUtils.isEmpty(randomNum)) {
            if (i == 1) {
                map.put("body", "【华为乾坤】您的登录验证码为："+randomNum+"，验证码3分钟有效，为了保证您的帐户安全，请勿向任何人提供此验证码。");
            }
            if (i == 0) {
                map.put("body", "【华为乾坤】 "+randomNum);
            }
        }
        StringBuilder sb = new StringBuilder();
        String temp = "";

        for (String s : map.keySet()) {
            try {
                temp = URLEncoder.encode(map.get(s), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            sb.append(s).append("=").append(temp).append("&");
        }

        return sb.deleteCharAt(sb.length()-1).toString();
    }


    /**
        * 构造X-WSSE参数值
     * @param appKey
     * @param appSecret
     * @return
             */
    static String buildWsseHeader(String appKey, String appSecret) {
        if (null == appKey || null == appSecret || appKey.isEmpty() || appSecret.isEmpty()) {
            log.info("buildWsseHeader(): appKey or appSecret is null.");
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        String time = sdf.format(new Date()); //Created

        log.info( "time"+time);
        String nonce = UUID.randomUUID().toString().replace("-", ""); //Nonce
        log.info( "nonce:"+nonce);
        MessageDigest md;
        byte[] passwordDigest = null;
        String string = null;
        try {
            md = MessageDigest.getInstance("SHA-256");
            string = nonce+time+appSecret;
            md.update(string.getBytes(StandardCharsets.UTF_8));
            passwordDigest = md.digest();
            string = Hex.encodeHexString(passwordDigest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        //如果JDK版本是1.8,请加载原生Base64类,并使用如下代码
        String passwordDigestBase64Str = Base64.getEncoder().encodeToString(string.getBytes(StandardCharsets.UTF_8)); //PasswordDigest
        log.info("passwordDigestBase64Str "+passwordDigestBase64Str);
        return String.format(WSSE_HEADER_FORMAT, appKey, passwordDigestBase64Str, nonce, time);
    }

}
